home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 42 / wind7.prf < prev    next >
Text File  |  1986-07-17  |  18KB  |  406 lines

  1. .!****************************************************************************
  2. .! 
  3. .! ANTIC PUBLISHING INC., COPYRIGHT 1985.  REPRINTED BY PERMISSION.
  4. .!
  5. .! ** Professional GEM ** by Tim Oren
  6. .!
  7. .! Proff File by ST enthusiasts at
  8. .! Case Western Reserve University
  9. .! Cleveland, Ohio
  10. .! uucp : decvax!cwruecmp!bammi
  11. .! csnet: bammi@case
  12. .! arpa : bammi%case@csnet-relay
  13. .! compuserve: 71515,155
  14. .!
  15. .!****************************************************************************
  16. .!
  17. .!
  18. .!****************************************************************************
  19. .!
  20. .!            Begin Part 7
  21. .!
  22. .!****************************************************************************
  23. .!
  24. .PART VII Menu Structures
  25. .SH HAPPY NEW YEAR
  26. This is article number seven in the ST
  27. PRO GEM series, and the first for 1986.  In this installment,
  28. I will be discussing GEM menu structures and how to use them
  29. in your application.  There is  also a short Feedback
  30. response section.  You will find the download file containing
  31. the code for this column in the file GEMCL7.C in DL3 of the
  32. ATARI16 SIG (PCS-58).
  33. .SH MENU BASICS
  34. In ST GEM, the menu consists of a bar
  35. across the top of the screen which displays several sub-menu
  36. titles.  Touching one of the titles causes it to highlight,
  37. and an associated "drop-down" to be drawn  directly below on
  38. the screen.  This drop-down may be dismissed by moving  to
  39. another title, or by clicking the mouse off of the drop-down.
  40. .PP
  41. To make a selection, the mouse is moved over the
  42. drop-down.  Each  valid selection is highlighted when the
  43. mouse touches it.  Clicking the mouse  while over one of
  44. these selections picks that item.  GEM then undraws the
  45. drop-down, and sends a message to your application giving the
  46. object number  of the title bar entry, and the object number
  47. of the drop-down item which  were selected by the user.  The
  48. selected title entry is left highlighted  while your code
  49. processes the request.
  50. .SH  MENU STRUCTURES
  51. The data structure which defines a GEM
  52. menu is (surprise!) an object tree, just like the dialogs and
  53. panels which we have discussed before.  However, the
  54. operations of the GEM menu manager are quite different from
  55. those of the form manager, so the internal design of the menu
  56. tree has some curious constraints.
  57. .PP
  58. The best way to understand these constraints is to look
  59. at an  example.  The first item in the download is the object
  60. structure (only) of the menu tree from the GEM Doodle/Demo
  61. sample application.
  62. .PP
  63. The ROOT of a menu tree is sized to fit the entire
  64. screen.  To satisfy the visual hierarchy principle (see
  65. article #5), the screen is divided into two parts: THE BAR,
  66. containing the menu titles, and THE SCREEN, while contains
  67. the drop-downs when they are drawn.  Each of these areas is
  68. defined by an object of the same name, which are the only two
  69. objects linked directly below the ROOT of a menu tree.  You
  70. will notice an important implication of this structure:  The
  71. menu titles and their associated drop-downs are stored in
  72. entirely different subtrees of the menu!
  73. .PP
  74. While examining THE BAR in the example listing, you may
  75. notice that its OB_HEIGHT is very large (513).  In
  76. hexadecimal this is 0x0201.  This defines a height for THE
  77. BAR of one character plus two pixels used for spacing.  THE
  78. BAR and its subtree are the only objects which are drawn on
  79. the screen in the menu's quiescent state.
  80. .PP
  81. The only offspring object of THE BAR is THE ACTIVE.  This
  82. object defines the part of THE BAR which is covered by menu
  83. titles.  The screen rectangle belonging to THE ACTIVE is used
  84. by the GEM screen manager when it  waits for the mouse to
  85. enter an active menu title.  Notice that THE ACTIVE and its
  86. offspring also have OB_HEIGHTs with pixel residues.
  87. .PP
  88. The actual menu titles are linked left to right in order
  89. below THE ACTIVE.  Their OB_Xs and OB_WIDTHs are arranged so
  90. that they  completely cover THE ACTIVE.  Normally, the title
  91. objects are typed  G_TITLE, a special type which assures that
  92. the title bar margins are correctly drawn.
  93. .PP
  94. THE SCREEN is the parent object of the drop-down boxes
  95. themselves. They are linked left to right in an order
  96. identical with their titles, so  that the menu manager can
  97. make the correct correspondence at run-time.  The OB_X of
  98. each drop-down is set so that it is positioned below its
  99. title on the screen.
  100. .PP
  101. Notice that it is safe to overlap the drop-downs within a
  102. menu,  since only one of them will be displayed at any time.
  103. There is one constraint on the boxes however:  They must be
  104. no greater than a quarter screen in total size.  This is the
  105. size of the off-screen blit buffer which is used by GEM to
  106. store the screen contents when the drop-down is drawn.  If
  107. you exceed this size, not all the screen under the drop-down
  108. will be restored, or the ST may crash!
  109. .PP
  110. The entries within a drop-down are usually G_STRINGs,
  111. which are optimized for drawing speed.  The rectangles of
  112. these entries must  completely cover the drop-down, or the
  113. entire drop-down will be inverted  when the mouse touches an
  114. uncovered area!  Techniques for using objects  other than
  115. G_STRINGs are discussed later in this column.
  116. .PP
  117. The first title and its corresponding drop-down are
  118. special.  The title name, by custom, is set to DESK.  The
  119. drop-down must contain exactly  eight G_STRING objects.  The
  120. first (again by custom) is the INFO entry,  which usually
  121. leads to a dialog displaying author and copyright information
  122. for your application.  The next is a separator string of
  123. dashes with the DISABLED flag set.  The following six objects
  124. are dummy strings which GEM fills in with the names of desk
  125. accessories when your menu is loaded.
  126. .PP
  127. The purpose of this description of menu trees is to give
  128. you an understanding of what lies "behind the scenes" in the
  129. next section, which describes the run-time menu library
  130. calls.  In practice, the Resource Construction Set provides
  131. "blank menus" which include all of the required elements, and
  132. it also enforces the constraints on internal structure.  You
  133. only need to worry about these if you modify the menu tree
  134. "on-the-fly".
  135. .SH USING THE MENU
  136. once you have loaded the application's
  137. resource, you can ask the AES to install your menu.  You must
  138. first get the address of the menu tree within the resource
  139. using:
  140. .FB rsrc_gaddr()
  141. rsrc_gaddr(R_TREE, MENUTREE, &ad_menu);
  142. .FE
  143. assuming that MENUTREE is the name you gave the menu in the
  144. RCS, and that ad_menu is a LONG which will receive the
  145. address.  Then you call the AES to establish the menu:
  146. .FB menu_bar()
  147. menu_bar(ad_menu, TRUE);
  148. .FE
  149. At this point, the AES draws your menu bar on the screen and
  150. animates it when the user moves the mouse into the title
  151. area.
  152. .PP
  153. The AES indicates that the user has made a menu selection
  154. by sending your application a message.  The message type is
  155. MN_SELECTED,  which will be stored in msg[0], the first
  156. location in the message  returned by evnt_multi().
  157. .PP
  158. The AES also stores the object number of the selected
  159. menu's  title in msg[3], and the object number of the
  160. selected menu item in msg[4].  Generally, your application
  161. will process menu messages with nested C switch statements.
  162. The outer switch will have one case for each menu title, and
  163. the inner switch statements will have a case for each entry
  164. within the selected menu.  (This implies that you must give a
  165. name to each title and to each menu entry when you create the
  166. menu in the RCS.)
  167. .PP
  168. After the user has made a menu selection, the AES leaves
  169. the title of the chosen menu in reverse video to indicate
  170. that your application is busy processing the message.  When
  171. you done with whatever action is indicated, you need to
  172. return the title to a normal state. This is done with
  173. .FB menu_tnormal()
  174. menu_tnormal(ad_menu, msg[3], TRUE);
  175. .FE
  176. .sp 1
  177. .ce 1
  178. (Remember that msg[3] is the title's object number.)
  179. .sp 1
  180. When your application is ready to terminate, it should
  181. delete its menu bar.  Do this with the call:
  182. menu_bar(ad_menu, FALSE);
  183. .SH GETTING FANCY
  184. The techniques above represent the bare
  185. minimum to handle menus.  In most cases, however, you will
  186. want your menus to be more "intelligent" in displaying the
  187. user's options.  For instance, you can prevent many user
  188. errors by disabling inappropriate choices, or you can save
  189. space on drop-downs by showing only one line for a toggle and
  190. altering its text or placing and removing a check mark when
  191. the state is changed.  This section discusses these and other
  192. advanced techniques.
  193. .PP
  194. It is a truism of user interface design that the best way
  195. to deal with an error is not to let it happen in the first
  196. place.  It  many cases, you can apply this principle to GEM
  197. menus by disabling  choices which should not be used.  If
  198. your application uses a "selection  precedes action" type of
  199. interface, the type of object selected may  give the
  200. information needed to do this.   Alternately, the state of
  201. the  underlying program may render certain menu choices
  202. illegal.
  203. .PP
  204. GEM provides a call to disable and re-enable menu
  205. options. The call is:
  206. .FB menu_ienable()
  207. menu_ienable(ad_menu, ENTRY, FALSE);
  208. .FE
  209. to disable a selection.  The entry will be grayed out when
  210. it is drawn, and will not invert under the mouse and will not
  211. be selected by the user. Substituting TRUE for FALSE
  212. re-enables the option.  ENTRY is the name  of the object
  213. which is being affected, as assigned in the RCS.
  214. .PP
  215. Note that menu_ienable() will not normally affect the
  216. appearance or operation of menu TITLE entries.  However,
  217. there is an undocumented feature which allows this.  If ENTRY
  218. is replaced by the object number of a title bar entry with
  219. its top bit set, then the entire associated drop-down will be
  220. disabled or re-enabled as requested, and the title's
  221. appearance will be changed.  But, be warned that this feature
  222. did not work reliably in some early versions of GEM.  Test it
  223. on your copy of ST GEM, and use it with caution when you
  224. cannot control the version under which your application may
  225. run.
  226. .PP
  227. It is also possible to disable menu entries by directly
  228. altering the DISABLED attribute within the OB_STATE word.
  229. The routines enab_obj() and disab_obj() in the download show
  230. how this is done.  They are also used in set_menu(), which
  231. follows them immediately.
  232. .PP
  233. Set_menu() is a utility which is useful when you wish to
  234. simultaneously enable or disable many entries in the menu
  235. when the program's state changes or a new object is selected
  236. by the user.   It is called with
  237. .FB set_menu()
  238. set_menu(ad_menu, vector);
  239. .FE
  240. where vector is a pointer to an array of WORDs.  The first
  241. word of the array determines the default state of menu
  242. entries.  If it is TRUE, then set_menu() enables all entries
  243. in every drop-down of the menu tree, except that the DESK
  244. drop-down is unaffected.  If it is FALSE, then every menu
  245. entry is disabled.
  246. .PP
  247. The following entries in the array are the numbers of
  248. menu entries which are to be toggled to the reverse of the
  249. default state. This list is terminated by a zero entry.
  250. .PP
  251. The advantage of set_menu() is that it allows you to
  252. build a collection of menu state arrays, and associate one
  253. with each type of user-selected object, program state, and so
  254. on.  Changing the status of the menu tree may then be
  255. accomplished with a single call.
  256. .SH CHECK, PLEASE?
  257. One type of state indicator which may
  258. appear  within a drop-down is a checkmark next to an entry.
  259. You can add the  checkmark with the call:
  260. .FB menu_icheck()
  261. menu_icheck(ad_menu, ENTRY, TRUE);
  262. .FE
  263. and remove it by replacing the TRUE with FALSE.  As above,
  264. ENTRY is the name of the menu entry of interest.  The
  265. checkmark appears inside the left boundary of the entry
  266. object, so leave some space for it.
  267. .PP
  268. The menu_icheck() call is actually changing the state of
  269. the CHECKED flag within the entry object's OB_STATE word.  If
  270. necessary, you may alter the flag directly using do_obj() and
  271. undo_obj() from the download.
  272. .SH  NOW YOU SEE IT, NOW YOU DON'T
  273. You can also alter the
  274. text  which appears in a particular menu entry (assuming that
  275. the entry is  a G_STRING object).  The call
  276. .FB menu_text()
  277. menu_text(ad_menu, ENTRY, ADDR(text));
  278. .FE
  279. will substitute the null-terminated string pointed to by
  280. text for whatever is currently in ENTRY.  Remember to make
  281. the drop-down wide enough to handle the largest text string
  282. which you may substitute.  In the interests of speed,
  283. G_STRINGs drawn within drop-downs are not clipped, so you may
  284. get garbage characters on the desktop if you do not size the
  285. drop-down properly!
  286. .PP
  287. The menu_text() call actually alters the OB_SPEC field of
  288. the menu entry object to point to the string which you
  289. specify.  Since the menu tree is a static data structure
  290. which may be directly accessed by the AES at any time, be
  291. sure that the string is also statically allocated and that it
  292. is not modified without first being delinked from the menu
  293. tree. Failure to do this may result in random crashes when
  294. the user accesses the drop-down!
  295. .SH LUNCH AND DINNER MENUS
  296. Some applications may have such
  297. a wide  range of operations that they need more than one menu
  298. bar at different  times.  There is no problem with having
  299. more than one menu tree in a  resource, but the AES can only
  300. keep track of one at a time.  Therefore,  to switch menus you
  301. need to use menu_bar(ad_menu1, FALSE); to release  the first
  302. menu, then use menu_bar(ad_menu2, TRUE); to load the second
  303. menu tree.
  304. .PP
  305. Changing the entire menu is a drastic action.  Out of
  306. consideration for your user, it should be associated with
  307. some equally obvious change in the application which has just
  308. been manually requested.  An example  might be changing from
  309. spreadsheet to data graphing mode in a multi-function
  310. program.
  311. .SH DO IT YOURSELF
  312. In a future column, I will discuss how
  313. to set up user-defined drawing objects.  If you have already
  314. discovered them  on your own, you can use them within a
  315. drop-down or as a title entry.
  316. .PP
  317. If the user-defined object is within a drop-down, its
  318. associated drawing code will be called once when the
  319. drop-down is first drawn. It will then be called in
  320. "state-change" mode when the entry is highlighted (inverted).
  321. This allows you to use non-standard methods to show
  322. selection, such as outlines.
  323. .PP
  324. If you try to insert a user-defined object within the
  325. menu title area, remember that the G_TITLE object which you
  326. are replacing includes part of the dark margin of the bar.
  327. You will need to experiment with your object drawing code to
  328. replicate this effect.
  329. .SH MAKE PRETTY
  330. There are a number of menu formatting
  331. conventions which have become standard practice.  Using these
  332. gives your application a recognizable "look-and-feel" and
  333. helps users learn it.  The following section reviews these
  334. conventions, and supplies a few hints and tricks to obtain a
  335. better appearance for you menus.
  336. .PP
  337. The second drop-down is customarily used as the FILE
  338. menu.  It  contains options related to loading and saving the
  339. files used by the  application, as well as entries for
  340. clearing the workspace and  terminating the program.
  341. .PP
  342. You should avoid crowding the menu bar.  Leave a couple
  343. of spaces between each entry, and try not to use more than
  344. 70% of the bar.  Not only does this look better, but you will
  345. have space for longer words if you translate your application
  346. to a foreign language.
  347. .PP
  348. Similarly, avoid cluttering menu drop-downs.  Try to keep
  349. the number of options to no more than ten unless they are
  350. clearly related, such as colors.  Separate off dissimilar
  351. entries with the standard disabled dashes line.  (If you are
  352. using set_menu(), remember to consider the separators when
  353. setting up the state vectors.)
  354. .PP
  355. If the number of options grows beyond this bound, it may
  356. be time to move them to a dialog box.  If so, it is a
  357. convention to put three dots following each menu entry which
  358. leads to a dialog. Also, allow a margin on the menu entries.
  359. Two leading blanks and a minimum of one trailing blank is
  360. standard, and allows room for checkmarks if they are used.
  361. .PP
  362. Dangerous menu options should be far away from common
  363. used entries, and are best separated with dashed lines.  Such
  364. options should either lead to a confirming go/no-go alert, or
  365. should have associated "undo" options.
  366. .PP
  367. After you have finished defining a menu drop-down with
  368. the RCS,  be sure that its entries cover the entire box.
  369. Then use ctrl-click to  select the drop-down itself, and SORT
  370. the entries top to bottom.  This  way the drop-down draws in
  371. smoothly top to bottom.
  372. .PP
  373. Finally, it is possible to put entries other than
  374. G_STRINGs into drop-downs.  In the RCS, you will need to
  375. import them via the clipboard from the Dialog mode.
  376. .PP
  377. Some non-string object, such as icons and images, will
  378. look odd  when they are inverted under the mouse.  There is a
  379. standard trick for  dealing with this problem.  Insert the
  380. icon or whatever in the drop-down first.  Then get a G_IBOX
  381. object and position and size it so that it covers the first
  382. object as well as the extra area you would like to be
  383. inverted.
  384. .PP
  385. Edit the G_IBOX to remove its border, and assign the
  386. entry name  to it.  Since the menu manager uses objc_find(),
  387. it will detect and invert this second object when the mouse
  388. moves into the drop-down.  (To see why, refer to article #5.)
  389. Finally, DO NOT SORT a drop-down which has been set  up this
  390. way!
  391. .SH  THAT'S IT FOR NOW!
  392. The next column will discuss some of
  393. the principles of designing GEM interfaces for applications.
  394. This topic is irreverantly known as GEM mythology or
  395. interface religion.  The subject for the following column is
  396. undecided.  I am considering mouse and keyboard messages, VDI
  397. drawing primitives, and the file selector as topics.  Let me
  398. know your preferences in the Feedback!
  399. .!
  400. .!
  401. .!*****************************************************************************
  402. .!*                                          *
  403. .!*                End Part 7                      *
  404. .!*                                          *
  405. .!*****************************************************************************
  406.